home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / TERMCAP.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  18KB  |  838 lines

  1. /*    SCCS Id: @(#)termcap.c    3.0    88/11/20
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #define MONATTK_H    /* comment line for pre-compiled headers */
  6. /* block some unused #defines to avoid overloading some cpp's */
  7. #include "hack.h"    /* for ROWNO, COLNO, *HI, *HE, *AS, *AE */
  8.  
  9. #include <ctype.h>    /* for isdigit() */
  10.  
  11. #include "termcap.h"
  12.  
  13. #if (!defined(SYSV) && !defined(HPUX)) || defined(TOS) || defined(UNIXPC)
  14. # ifndef LINT
  15. extern            /* it is defined in libtermlib (libtermcap) */
  16. # endif
  17.     short ospeed;    /* terminal baudrate; used by tputs */
  18. #else
  19. short    ospeed = 0;    /* gets around "not defined" error message */
  20. #endif
  21.  
  22.  
  23. #ifdef MICROPORT_286_BUG
  24. #define Tgetstr(key) (tgetstr(key,tbuf))
  25. #else
  26. #define Tgetstr(key) (tgetstr(key,&tbufptr))
  27. #endif /* MICROPORT_286_BUG **/
  28.  
  29. STATIC_DCL void FDECL(nocmov, (int, int));
  30. #ifdef TEXTCOLOR
  31. # ifdef TERMLIB
  32. #  ifdef OVLB
  33. static void NDECL(init_hilite);
  34. #  endif /* OVLB */
  35. # endif
  36. #endif
  37.  
  38. STATIC_VAR char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
  39. STATIC_VAR char *VS, *VE, *US, *UE;
  40. STATIC_VAR char *MR, *ME;
  41. #if 0
  42. STATIC_VAR char *MB, *MH;
  43. STATIC_VAR char *MD;     /* may already be in use below */
  44. #endif
  45. #ifdef TERMLIB
  46. # ifdef TEXTCOLOR
  47. STATIC_VAR char *MD;
  48. # endif
  49. STATIC_VAR int SG;
  50. #ifdef OVLB
  51. STATIC_OVL char PC = '\0';
  52. #else /* OVLB */
  53. STATIC_DCL char PC;
  54. #endif /* OVLB */
  55. STATIC_VAR char tbuf[512];
  56. #endif
  57.  
  58. #ifdef OVLB
  59. static char nullstr[] = "";
  60. #endif /* OVLB */
  61.  
  62. #ifndef TERMLIB
  63. STATIC_VAR char tgotobuf[20];
  64. # ifdef TOS
  65. #define tgoto(fmt, x, y)    (Sprintf(tgotobuf, fmt, y+' ', x+' '), tgotobuf)
  66. # else
  67. #define tgoto(fmt, x, y)    (Sprintf(tgotobuf, fmt, y+1, x+1), tgotobuf)
  68. # endif
  69. #endif /* TERMLIB */
  70.  
  71. #ifdef OVLB
  72.  
  73. void
  74. startup()
  75. {
  76. #ifdef TERMLIB
  77.     register const char *term;
  78.     register char *tptr;
  79.     char *tbufptr, *pc;
  80. #endif
  81.     register int i;
  82.  
  83. #ifdef TERMLIB
  84. # ifdef VMS
  85.     term = getenv("EMACS_TERM");
  86.     if (!term)
  87.         term = getenv("NETHACK_TERM");
  88.     if (!term)
  89. # endif
  90.     term = getenv("TERM");
  91. #endif
  92.     /* Set the default map symbols */
  93.     (void) memcpy((genericptr_t) showsyms, 
  94.         (genericptr_t) defsyms, sizeof showsyms);
  95.  
  96.  
  97. #ifdef TERMLIB
  98.     if(!term)
  99. #endif
  100. #if defined(TOS) && defined(__GNUC__) && defined(TERMLIB)
  101.         term = "builtin";        /* library has a default */
  102. #else
  103. # ifdef MACOS
  104.     /* dummy termcap for the Mac */
  105.     HO = "\033[H";
  106.     CL = "\033[2J";     /* a pseudo-ANSI termcap */
  107.     CE = "\033[K";
  108.     CM = "\033[%d;%dH"; /* not used */
  109.     UP = "\033[A";
  110.     ND = "\033[C";
  111.     XD = "\033[B";
  112.      BC = "\033[D";
  113.      TI = TE = SE = UE = US = HE = "\033[0m";
  114.      SO = "\033[1m";
  115.      AS = VS = VE = AE = "";
  116.      CO = COLNO;
  117.      LI = ROWNO + 3;
  118.      /* use special font ? */
  119.     {
  120.         extern short macflags;
  121.         if (macflags & fUseCustomFont)
  122.         {
  123.         Handle  theRes;
  124.         unsigned char   *sym;
  125.         short   i;
  126.  
  127.         sym = &showsyms[S_stone];
  128.         theRes = GetResource(HACK_DATA,102);
  129.         HLock(theRes);
  130.         strncpy((char *)sym,(char *)(*theRes),32);
  131.         HUnlock(theRes);
  132.         ReleaseResource(theRes);
  133.         }
  134.     }
  135. #  ifdef TEXTCOLOR
  136.     for (i = 0; i < MAXCOLORS; i++) {
  137.         hilites[i] = (char *) alloc(sizeof("E[cc"));
  138.         Sprintf(hilites[i], "\033[c%c", (char)(i+'a'));
  139.     }
  140. #  endif
  141. # else /* MACOS */
  142. # ifdef ANSI_DEFAULT
  143. #  ifdef TOS
  144.     {
  145.         CO = 80; LI = 25;
  146.         TI = VS = VE = TE = "";
  147.         HO = "\033H";
  148.         CL = "\033E";        /* the VT52 termcap */
  149.         CE = "\033K";
  150.         UP = "\033A";
  151.         CM = "\033Y%c%c";    /* used with function tgoto() */
  152.         ND = "\033C";
  153.         XD = "\033B";
  154.         BC = "\033D";
  155.         SO = "\033p";
  156.         SE = "\033q";
  157.         HI = "\033p";
  158. #ifdef TEXTCOLOR
  159.         HE = "\033q\033b\017";
  160.         for (i = 0; i < SIZE(hilites); i++) {
  161.             hilites[i] = (char *) alloc(sizeof("Eb1"));
  162.             Sprintf(hilites[i], (i%4)?"\033b%c" : "\033p", i);
  163.         }
  164. #else
  165.         HE = "\033q";
  166. #endif
  167.     }
  168. #  else /* TOS */
  169.     {
  170. #   ifdef DGK
  171.         get_scr_size();
  172.         if(CO < COLNO || LI < ROWNO+3)
  173.             setclipped();
  174. #   endif
  175.         HO = "\033[H";
  176.         CL = "\033[2J";        /* the ANSI termcap */
  177. /*        CD = "\033[J"; */
  178.         CE = "\033[K";
  179. #   ifndef TERMLIB
  180.         CM = "\033[%d;%dH";
  181. #   else
  182.         CM = "\033[%i%d;%dH";
  183. #   endif
  184.         UP = "\033[A";
  185.         ND = "\033[C";
  186.         XD = "\033[B";
  187. #   ifdef MSDOS    /* backspaces are non-destructive */
  188.         BC = "\b";
  189. #   else
  190.         BC = "\033[D";
  191. #   endif
  192.         HI = SO = "\033[1m";
  193.         US = "\033[4m";
  194.         MR = "\033[7m";
  195.         TI = HE = SE = UE = ME = "\033[0m";
  196.         /* strictly, SE should be 2, and UE should be 24,
  197.            but we can't trust all ANSI emulators to be
  198.            that complete.  -3. */
  199. #   if !defined(MSDOS) || (defined(TERMLIB) && defined(AMIGA))
  200.         AS = "\016";
  201.         AE = "\017";
  202. #   endif
  203.         TE = VS = VE = "";
  204. #   ifdef TEXTCOLOR
  205.         for (i = 0; i < MAXCOLORS / 2; i++) {
  206.             hilites[i] = (char *) alloc(sizeof("\033[0;3%dm"));
  207.             hilites[i+BRIGHT] = (char *) alloc(sizeof("\033[1;3%dm"));
  208. #    ifdef MSDOS
  209.             Sprintf(hilites[i], (i == BLUE ? "\033[1;3%dm" : "\033[0;3%dm"), i);
  210. #    else
  211.             Sprintf(hilites[i], "\033[0;3%dm", i);
  212. #    endif
  213.             Sprintf(hilites[i+BRIGHT], "\033[1;3%dm", i);
  214.         }
  215. #   endif
  216.         return;
  217.     }
  218. #  endif /* TOS */
  219. # else
  220.         error("Can't get TERM.");
  221. # endif /* ANSI_DEFAULT */
  222. # endif /* MACOS */
  223. #endif /* __GNUC__ && TOS && TERMCAP */
  224. #ifdef TERMLIB
  225.     tptr = (char *) alloc(1024);
  226.  
  227.     tbufptr = tbuf;
  228.     if(!strncmp(term, "5620", 4))
  229.         flags.nonull = 1;    /* this should be a termcap flag */
  230.     if(tgetent(tptr, term) < 1)
  231.         error("Unknown terminal type: %s.", term);
  232.     if(pc = Tgetstr("pc"))
  233.         PC = *pc;
  234. # ifdef TERMINFO
  235.     if(!(BC = Tgetstr("le"))) {    
  236. # else
  237.     if(!(BC = Tgetstr("bc"))) {    
  238. # endif
  239. # if !defined(MINIMAL_TERM) && !defined(HISX)
  240.         if(!tgetflag("bs"))
  241.             error("Terminal must backspace.");
  242. # endif
  243.         BC = tbufptr;
  244.         tbufptr += 2;
  245.         *BC = '\b';
  246.     }
  247. # ifdef MINIMAL_TERM
  248.     HO = NULL;
  249. # else
  250.     HO = Tgetstr("ho");
  251. # endif
  252.     /*
  253.      * LI and CO are set in ioctl.c via a TIOCGWINSZ if available.  If
  254.      * the kernel has values for either we should use them rather than
  255.      * the values from TERMCAP ...
  256.      */
  257. # ifndef DGK
  258.     if (!CO) CO = tgetnum("co");
  259.     if (!LI) LI = tgetnum("li");
  260. # else
  261. #  if defined(TOS) && defined(__GNUC__)
  262.     if (!strcmp(term, "builtin"))
  263.         get_scr_size();
  264.     else {
  265. #  endif
  266.     CO = tgetnum("co");
  267.     LI = tgetnum("li");
  268.     if (!LI || !CO)            /* if we don't override it */
  269.         get_scr_size();
  270. #  if defined(TOS) && defined(__GNUC__)
  271.     }
  272. #  endif
  273. # endif
  274.     if(CO < COLNO || LI < ROWNO+3)
  275.         setclipped();
  276.     if(!(CL = Tgetstr("cl")))
  277.         error("Hack needs CL.");
  278.     ND = Tgetstr("nd");
  279.     if(tgetflag("os"))
  280.         error("Hack can't have OS.");
  281.     CE = Tgetstr("ce");
  282.     UP = Tgetstr("up");
  283.     /* It seems that xd is no longer supported, and we should use
  284.        a linefeed instead; unfortunately this requires resetting
  285.        CRMOD, and many output routines will have to be modified
  286.        slightly. Let's leave that till the next release. */
  287.     XD = Tgetstr("xd");
  288. /* not:         XD = Tgetstr("do"); */
  289.     if(!(CM = Tgetstr("cm"))) {
  290.         if(!UP && !HO)
  291.             error("Hack needs CM or UP or HO.");
  292.         Printf("Playing hack on terminals without cm is suspect...\n");
  293.         getret();
  294.     }
  295.     SO = Tgetstr("so");
  296.     SE = Tgetstr("se");
  297.     US = Tgetstr("us");
  298.     UE = Tgetstr("ue");
  299.     SG = tgetnum("sg");    /* -1: not fnd; else # of spaces left by so */
  300.     if(!SO || !SE || (SG > 0)) SO = SE = US = UE = nullstr;
  301.     TI = Tgetstr("ti");
  302.     TE = Tgetstr("te");
  303.     VS = VE = nullstr;
  304. # ifdef TERMINFO
  305.     VS = Tgetstr("eA");    /* enable graphics */
  306. # endif
  307. # if 0
  308.     MB = Tgetstr("mb");    /* blink */
  309.     MD = Tgetstr("md");    /* boldface */
  310.     MH = Tgetstr("mh");    /* dim */
  311. # endif
  312.     MR = Tgetstr("mr");    /* reverse */
  313.     ME = Tgetstr("me");
  314.  
  315.     /* Get rid of padding numbers for HI and HE.  Hope they
  316.      * aren't really needed!!!  HI and HE are ouputted to the
  317.      * pager as a string - so how can you send it NULLS???
  318.      *  -jsb
  319.      */
  320.         HI = (char *) alloc((unsigned)(strlen(SO)+1));
  321.         HE = (char *) alloc((unsigned)(strlen(SE)+1));
  322.         i = 0;
  323.         while(isdigit(SO[i])) i++;
  324.         Strcpy(HI, &SO[i]);
  325.         i = 0;
  326.         while(isdigit(SE[i])) i++;
  327.         Strcpy(HE, &SE[i]);
  328.     AS = Tgetstr("as");
  329.     AE = Tgetstr("ae");
  330.     CD = Tgetstr("cd");
  331. # ifdef TEXTCOLOR
  332.     MD = Tgetstr("md");
  333. # endif
  334.     set_whole_screen();        /* uses LI and CD */
  335.     if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n");
  336.     free((genericptr_t)tptr);
  337. # ifdef TEXTCOLOR
  338.     init_hilite();
  339. #  if defined(TOS) && defined(__GNUC__)
  340.     if (!strcmp(term, "builtin"))
  341.         HE="\033q\033b3\033c0";    /* to turn off colors, too */
  342. #  endif
  343. # endif
  344. #endif /* TERMLIB */
  345. }
  346.  
  347. void
  348. start_screen()
  349. {
  350.     xputs(TI);
  351.     xputs(VS);
  352.     if (flags.DECgraphics) {
  353.         /* select the line-drawing character set as the alternate
  354.          * character set
  355.          * do not select NA ASCII as the primary character set
  356.          * since people may reasonably be using the UK set
  357.          */
  358.         xputs("\033)0");
  359.         /* 'as' and 'ae' are missing from some termcaps */
  360.         if (!AS) AS = "\016";  /* ^N */
  361.         if (!AE) AE = "\017";  /* ^O */
  362.     }
  363. }
  364.  
  365. void
  366. end_screen()
  367. {
  368.     clear_screen();
  369.     xputs(VE);
  370.     xputs(TE);
  371. }
  372.  
  373. /* Cursor movements */
  374.  
  375. #endif /* OVLB */
  376. #ifdef OVL0
  377.  
  378. #ifdef CLIPPING
  379. /* if (x,y) is currently viewable, move the cursor there and return TRUE */
  380. boolean
  381. win_curs(x, y)
  382. int x, y;
  383. {
  384.     if (clipping && (x<=clipx || x>=clipxmax || y<=clipy || y>=clipymax))
  385.         return FALSE;
  386.     y -= clipy;
  387.     x -= clipx;
  388.     curs(x, y+2);
  389.     return TRUE;
  390. }
  391. #endif
  392.  
  393. #endif /* OVLB */
  394. #ifdef OVLB
  395. void
  396. curs(x, y)
  397. register int x, y;    /* not xchar: perhaps xchar is unsigned and
  398.                curx-x would be unsigned as well */
  399. {
  400.     if (y == cury && x == curx)
  401.         return;
  402.     if(!ND && (curx != x || x <= 3)) {    /* Extremely primitive */
  403.         cmov(x, y);            /* bunker!wtm */
  404.         return;
  405.     }
  406.     if(abs(cury-y) <= 3 && abs(curx-x) <= 3)
  407.         nocmov(x, y);
  408.     else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
  409.         (void) putchar('\r');
  410.         curx = 1;
  411.         nocmov(x, y);
  412.     } else if(!CM) {
  413.         nocmov(x, y);
  414.     } else
  415.         cmov(x, y);
  416. }
  417.  
  418. #endif /* OVLB */
  419. #ifdef OVL0
  420. /* Note to OVLx tinkerers.  The placement of this overlay controls the location
  421.    of the function xputc().  This function is not currnently in trampoli.[ch]
  422.    files for what is deemed to be performance reasons.  If this define is moved
  423.    and or xputc() is taken out of the ROOT overlay, then action must be taken
  424.    in trampoli.[ch]. */
  425.  
  426. STATIC_OVL void
  427. nocmov(x, y)
  428. int x,y;
  429. {
  430.     if (cury > y) {
  431.         if(UP) {
  432.             while (cury > y) {    /* Go up. */
  433.                 xputs(UP);
  434.                 cury--;
  435.             }
  436.         } else if(CM) {
  437.             cmov(x, y);
  438.         } else if(HO) {
  439.             home();
  440.             curs(x, y);
  441.         } /* else impossible("..."); */
  442.     } else if (cury < y) {
  443.         if(XD) {
  444.             while(cury < y) {
  445.                 xputs(XD);
  446.                 cury++;
  447.             }
  448.         } else if(CM) {
  449.             cmov(x, y);
  450.         } else {
  451.             while(cury < y) {
  452.                 xputc('\n');
  453.                 curx = 1;
  454.                 cury++;
  455.             }
  456.         }
  457.     }
  458.     if (curx < x) {        /* Go to the right. */
  459.         if(!ND) cmov(x, y); else    /* bah */
  460.             /* should instead print what is there already */
  461.         while (curx < x) {
  462.             xputs(ND);
  463.             curx++;
  464.         }
  465.     } else if (curx > x) {
  466.         while (curx > x) {    /* Go to the left. */
  467.             xputs(BC);
  468.             curx--;
  469.         }
  470.     }
  471. }
  472.  
  473. void
  474. cmov(x, y)
  475. register int x, y;
  476. {
  477. #ifdef MACOS
  478.     mcurs(x-1, y-1);
  479. #else
  480.     xputs(tgoto(CM, x-1, y-1));
  481. #endif
  482.     cury = y;
  483.     curx = x;
  484. }
  485.  
  486. /* See note at OVLx ifdef above.   xputc() is a special function. */
  487. void
  488. xputc(c)
  489. char c;
  490. {
  491. #ifdef MACOS
  492.     mputc(c);
  493. #else
  494.     (void) fputc(c, stdout);
  495. #endif
  496. }
  497.  
  498. void
  499. xputs(s)
  500. const char *s;
  501. {
  502. #ifndef MACOS
  503. # ifndef TERMLIB
  504.     (void) fputs(s, stdout);
  505. # else
  506. #  ifdef __STDC__
  507.     tputs(s, 1, (int (*)())xputc);
  508. #  else
  509.     tputs(s, 1, xputc);
  510. #  endif
  511. # endif
  512. #else
  513.     mputs(s);
  514. #endif
  515. }
  516.  
  517. void
  518. cl_end() {
  519.     if(CE)
  520.         xputs(CE);
  521.     else {    /* no-CE fix - free after Harold Rynes */
  522.         /* this looks terrible, especially on a slow terminal
  523.            but is better than nothing */
  524.         register int cx = curx, cy = cury;
  525.  
  526.         while(curx < CO) {
  527.             xputc(' ');
  528.             curx++;
  529.         }
  530.         curs(cx, cy);
  531.     }
  532. }
  533.  
  534. #endif /* OVL0 */
  535. #ifdef OVLB
  536.  
  537. void
  538. clear_screen() {
  539.     xputs(CL);
  540.     home();
  541. }
  542.  
  543. #endif /* OVLB */
  544. #ifdef OVL0
  545.  
  546. void
  547. home()
  548. {
  549.     if(HO)
  550.         xputs(HO);
  551.     else if(CM)
  552.         xputs(tgoto(CM, 0, 0));
  553.     else
  554.         curs(1, 1);    /* using UP ... */
  555.     curx = cury = 1;
  556. }
  557.  
  558. void
  559. standoutbeg()
  560. {
  561.     if(SO) xputs(SO);
  562. }
  563.  
  564. void
  565. standoutend()
  566. {
  567.     if(SE) xputs(SE);
  568. }
  569.  
  570. void
  571. revbeg()
  572. {
  573.     if(MR) xputs(MR);
  574. }
  575.  
  576. #if 0    /* if you need one of these, uncomment it (here and in extern.h) */
  577. void
  578. boldbeg()
  579. {
  580.     if(MD) xputs(MD);
  581. }
  582.  
  583. void
  584. blinkbeg()
  585. {
  586.     if(MB) xputs(MB);
  587. }
  588.  
  589. void
  590. dimbeg()
  591. /* not in most termcap entries */
  592. {
  593.     if(MH) xputs(MH);
  594. }
  595. #endif
  596.  
  597. void
  598. m_end()
  599. {
  600.     if(ME) xputs(ME);
  601. }
  602.  
  603. #endif /* OVL0 */
  604. #ifdef OVLB
  605.  
  606. void
  607. backsp()
  608. {
  609.     xputs(BC);
  610. }
  611.  
  612. void
  613. bell()
  614. {
  615.     if (flags.silent) return;
  616.     (void) putchar('\007');        /* curx does not change */
  617.     (void) fflush(stdout);
  618. }
  619.  
  620. #endif /* OVLB */
  621. #ifdef OVL0
  622.  
  623. #ifdef ASCIIGRAPH
  624. void
  625. graph_on() {
  626.     if (AS) xputs(AS);
  627. }
  628.  
  629. void
  630. graph_off() {
  631.     if (AE) xputs(AE);
  632. }
  633. #endif
  634.  
  635. #endif /* OVL0 */
  636. #ifdef OVL1
  637.  
  638. #if !defined(MSDOS) && !defined(MACOS)
  639. # ifdef VMS
  640. static const short tmspc10[] = {        /* from termcap */
  641.     0, 2000, 1333, 909, 743, 666, 333, 166, 83, 55, 50, 41, 27, 20, 13, 10,
  642.     5
  643. };
  644. # else
  645. static const short tmspc10[] = {        /* from termcap */
  646.     0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
  647. };
  648. # endif
  649. #endif
  650.  
  651. void
  652. delay_output() {
  653.     /* delay 50 ms - could also use a 'nap'-system call */
  654.     /* BUG: if the padding character is visible, as it is on the 5620
  655.        then this looks terrible. */
  656. #if defined(MSDOS) || defined(MACOS)
  657.     /* simulate the delay with "cursor here" */
  658.     register int i;
  659.     for (i = 0; i < 3; i++) {
  660.         cmov(curx, cury);
  661.         (void) fflush(stdout);
  662.     }
  663. #else /* MSDOS || MACOS */
  664.     if(!flags.nonull)
  665. # ifdef TERMINFO
  666.         /* cbosgd!cbcephus!pds for SYS V R2 */
  667. #  ifdef __STDC__
  668.         tputs("$<50>", 1, (int (*)())xputc);
  669. #  else
  670.         tputs("$<50>", 1, xputc);
  671. #  endif
  672. # else
  673. #  ifdef __STDC__
  674.         tputs("50", 1, (int (*)())xputc);
  675. #  else
  676.         tputs("50", 1, xputc);
  677. #  endif
  678. # endif
  679.  
  680.     else if(ospeed > 0 && ospeed < SIZE(tmspc10)) if(CM) {
  681.         /* delay by sending cm(here) an appropriate number of times */
  682.         register int cmlen = strlen(tgoto(CM, curx-1, cury-1));
  683.         register int i = 500 + tmspc10[ospeed]/2;
  684.  
  685.         while(i > 0) {
  686.             cmov(curx, cury);
  687.             i -= cmlen*tmspc10[ospeed];
  688.         }
  689.     }
  690. #endif /* MSDOS || MACOS */
  691. }
  692.  
  693. #endif /* OVL1 */
  694. #ifdef OVLB
  695.  
  696. void
  697. cl_eos()            /* free after Robert Viduya */
  698. {                /* must only be called with curx = 1 */
  699.  
  700.     if(CD)
  701.         xputs(CD);
  702.     else {
  703.         register int cx = curx, cy = cury;
  704.         while(cury <= LI-2) {
  705.             cl_end();
  706.             xputc('\n');
  707.             curx = 1;
  708.             cury++;
  709.         }
  710.         cl_end();
  711.         curs(cx, cy);
  712.     }
  713. }
  714.  
  715. #if defined(TEXTCOLOR) && defined(TERMLIB)
  716. # ifdef UNIX
  717. /*
  718.  * Sets up color highlighting, using terminfo(4) escape sequences (highlight
  719.  * code found in pri.c).  It is assumed that the background color is black.
  720.  */
  721. /* terminfo indexes for the basic colors it guarantees */
  722. #define COLOR_BLACK   1        /* fake out to avoid black on black */
  723. #define COLOR_BLUE    1
  724. #define COLOR_GREEN   2
  725. #define COLOR_CYAN    3
  726. #define COLOR_RED     4
  727. #define COLOR_MAGENTA 5
  728. #define COLOR_YELLOW  6
  729. #define COLOR_WHITE   7
  730.  
  731. /* map ANSI RGB to terminfo BGR */
  732. const int ti_map[8] = {
  733.     COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW,
  734.     COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE };
  735.  
  736. static void
  737. init_hilite()
  738. {
  739.     register int c;
  740. #  ifdef TERMINFO
  741.     char *setf, *scratch;
  742.     extern char *tparm();
  743. #  endif
  744.  
  745.     for (c = 0; c < MAXCOLORS; c++)
  746.         hilites[c] = HI;
  747.  
  748. #  ifdef TERMINFO
  749.     if (tgetnum("Co") < 8 || (setf = tgetstr("Sf", 0)) == NULL)
  750.         return;
  751.  
  752.     for (c = 0; c < MAXCOLORS / 2; c++) {
  753.           scratch = tparm(setf, ti_map[c]);
  754.         hilites[c] = (char *) alloc(strlen(scratch) + 1);
  755.         hilites[c+BRIGHT] = (char*) alloc(strlen(scratch)+strlen(MD)+1);
  756.         Strcpy(hilites[c], scratch);
  757.         Strcpy(hilites[c+BRIGHT], MD);
  758.         Strcat(hilites[c+BRIGHT], scratch);
  759.     }
  760. #  endif
  761. }
  762.  
  763. # else /* UNIX */
  764.  
  765. /*
  766.  * Sets up highlighting sequences, using ANSI escape sequences (highlight code
  767.  * found in pri.c).  The termcap entry for HI (from SO) is scanned to find the
  768.  * background color.
  769.  */
  770.  
  771. static void
  772. init_hilite()
  773. {
  774. #  ifdef TOS
  775.     int c;
  776. #  else
  777.     int backg = BLACK, foreg = WHITE, len;
  778.     register int c, color;
  779. #  endif
  780.  
  781.     for (c = 0; c < SIZE(hilites); c++)
  782.         hilites[c] = HI;
  783.  
  784. #  ifdef TOS
  785.     hilites[BROWN] = "\033b0\033c1";
  786.     hilites[RED] = "\033b1";
  787.     hilites[MAGENTA] = hilites[MAGENTA|BRIGHT] = "\033b1\033c2";
  788.     hilites[CYAN] = hilites[CYAN|BRIGHT] = "\033b3\033c2";
  789.     hilites[BLUE] = hilites[BLUE|BRIGHT] = "\033b2";
  790.     hilites[GREEN] = hilites[GREEN|BRIGHT] = "\033b2\033c3";
  791.     hilites[GRAY] = "\033b3\033c0";
  792.     hilites[ORANGE_COLORED] = "\033b3\033c1";
  793.     hilites[YELLOW] = "\033b1\033c3";
  794.     hilites[WHITE] = "\033b0\033c3";
  795. #  else /* TOS */
  796.     /* find the background color, HI[len] == 'm' */
  797.     len = strlen(HI) - 1;
  798.  
  799.     if (HI[len] != 'm' || len < 3) return;
  800.  
  801.     c = 2;
  802.     while (c < len) {
  803.         if ((color = atoi(&HI[c])) == 0) {
  804.         /* this also catches errors */
  805.         foreg = WHITE; backg = BLACK;
  806.         /*
  807.         } else if (color == 1) {
  808.         foreg |= BRIGHT;
  809.         */
  810.         } else if (color >= 30 && color <= 37) {
  811.         foreg = color - 30;
  812.         } else if (color >= 40 && color <= 47) {
  813.         backg = color - 40;
  814.         }
  815.         while (isdigit(HI[++c]));
  816.         c++;
  817.     }
  818.  
  819.     for (c = 0; c < MAXCOLORS / 2; c++)
  820.         /* avoid invisibility */
  821.         if (foreg != c && backg != c) {
  822.         hilites[c] = (char *) alloc(sizeof("\033[0;3%d;4%dm"));
  823.         hilites[c+BRIGHT] = (char *) alloc(sizeof("\033[1;3%d;4%dm"));
  824. #ifdef MSDOS    /* brighten low-visibility colors */
  825.         if (c == BLUE)
  826.             Sprintf(hilites[c], "\033[1;3%d;4%dm", c, backg);
  827.         else
  828. #endif
  829.         Sprintf(hilites[c], "\033[0;3%d;4%dm", c, backg);
  830.         Sprintf(hilites[c+BRIGHT], "\033[1;3%d;4%dm", c, backg);
  831.         }
  832. #  endif /* TOS */
  833. }
  834. # endif /* UNIX */
  835. #endif /* TEXTCOLOR */
  836.  
  837. #endif /* OVLB */
  838.